package com.alinesno.cloud.common.core.services.impl;

import java.util.List;
import java.util.Optional;

import javax.transaction.Transactional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.Assert;

import com.alinesno.cloud.common.core.orm.entity.BaseEntity;
import com.alinesno.cloud.common.core.orm.repository.IBaseJpaRepository;
import com.alinesno.cloud.common.core.services.IBaseService;

/**
 * 服务实现基类
 * @author LuoAnDong
 * @since 2018年11月20日 下午8:05:00
 * @param <Jpa>
 * @param <Entity>
 * @param <ID>
 */
public class IBaseServiceImpl<Jpa extends IBaseJpaRepository<Entity, ID>  , Entity extends BaseEntity , ID> implements IBaseService<Jpa, Entity, ID> {

	private static final Logger log = LoggerFactory.getLogger(IBaseServiceImpl.class) ; 
	
	@Autowired
	protected Jpa jpa ; 
	
	@Override
	public List<Entity> findAll() {
		return jpa.findAll() ; 
	}

	@Override
	public List<Entity> findAll(Sort sort) {
		return jpa.findAll(sort);
	}

	@Override
	public List<Entity> findAllById(Iterable<ID> ids) {
		return jpa.findAllById(ids);
	}

	@Override
	public <S extends Entity> List<S> saveAll(Iterable<S> entities) {
		return jpa.saveAll(entities);
	}

	@Override
	public void flush() {
		jpa.flush(); 
	}

	@Override
	public <S extends Entity> S saveAndFlush(S entity) {
		return jpa.saveAndFlush(entity);
	}

	@Override
	public void deleteInBatch(Iterable<Entity> entities) {
		jpa.deleteInBatch(entities);
	}

	@Override
	public void deleteAllInBatch() {
		jpa.deleteAllInBatch();
	}

	@Override
	public Entity getOne(ID id) {
		return jpa.getOne(id);
	}

	@Override
	public <S extends Entity> List<S> findAll(Example<S> example) {
		return jpa.findAll(example);
	}

	@Override
	public <S extends Entity> List<S> findAll(Example<S> example, Sort sort) {
		return jpa.findAll(example, sort);
	}

	@Override
	public Page<Entity> findAll(Pageable pageable) {
		return jpa.findAll(pageable);
	}

	@Override
	public <S extends Entity> S save(S entity) {
		return jpa.save(entity) ;
	}

	@Override
	public Optional<Entity> findById(ID id) {
		return jpa.findById(id);
	}

	@Override
	public boolean existsById(ID id) {
		return jpa.existsById(id);
	}

	@Override
	public long count() {
		return jpa.count() ;
	}

	@Override
	public void deleteById(ID id) {
		jpa.deleteById(id);
	}

	@Override
	public void delete(Entity entity) {
		jpa.delete(entity);
	}

	@Override
	public void deleteAll(Iterable<? extends Entity> entities) {
		jpa.deleteAll(entities);
	}

	@Override
	public void deleteAll() {
		jpa.deleteAll();
	}

	@Override
	public <S extends Entity> Optional<S> findOne(Example<S> example) {
		return jpa.findOne(example);
	}

	@Override
	public <S extends Entity> Page<S> findAll(Example<S> example, Pageable pageable) {
		return jpa.findAll(example, pageable);
	}

	@Override
	public <S extends Entity> long count(Example<S> example) {
		return jpa.count(example) ;
	}

	@Override
	public <S extends Entity> boolean exists(Example<S> example) {
		return jpa.exists(example);
	}

	@Override
	public Optional<Entity> findOne(Specification<Entity> spec) {
		return jpa.findOne(spec);
	}

	@Override
	public List<Entity> findAll(Specification<Entity> spec) {
		return jpa.findAll(spec);
	}

	@Override
	public Page<Entity> findAll(Specification<Entity> spec, Pageable pageable) {
		return jpa.findAll(spec, pageable);
	}

	@Override
	public List<Entity> findAll(Specification<Entity> spec, Sort sort) {
		return jpa.findAll(spec, sort);
	}

	@Override
	public long count(Specification<Entity> spec) {
		return jpa.count(spec);
	}

	@Transactional
	@Override
	public void deleteByIds(ID[] ids) {
		for(ID id : ids) {
			jpa.deleteById(id);;
		}
	}

	@Override
	public boolean modifyHasStatus(ID id) {
		Assert.notNull(id,"主键不能为空.");
		Entity e = jpa.getOne(id) ; 
		log.debug("oldEntity:{} , hasStatus:{}" , e , e.getHasStatus());
		log.debug("e.getHasStatus()%2:{}" , e.getHasStatus()%2);
		e.setHasStatus((e.getHasStatus()+1)%2); 
		e = jpa.save(e) ; 
		
		log.debug("newEntity:{} , hasStatus:{}" , e , e.getHasStatus());
		return true ;
	}

	@Override
	public List<Entity> findAllByApplicationId(String applicationId) {
		return jpa.findAllByApplicationId(applicationId);
	}

	@Override
	public List<Entity> findAllByTenantId(String tenantId) {
		return jpa.findAllByTenantId(tenantId);
	}

	@Override
	public List<Entity> findAllByTenantIdAndApplicationId(String tenantId, String applicationId) {
		return jpa.findAllByTenantIdAndApplicationId(tenantId , applicationId);
	}

}
